﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Text;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.Win32;
using PowerGuiVsx.Module.Objects;

namespace PowerGuiVsx.Module
{
    [Cmdlet(VerbsCommon.Get, "VsPackage")]
    public class GetVsPackageCommand : PowerGuiVsxCommand 
    {
        protected override void BeginProcessing()
        {
            var registry = Package.GetService(typeof(SLocalRegistry)) as ILocalRegistry2;

            if (registry == null)
            {
                throw new NullReferenceException("Failed to retreive local registry service.");
            }

            string root;
            if (registry.GetLocalRegistryRoot(out root) != VSConstants.S_OK)
            {
                throw new ArgumentException("Cannot access local registry root.");
            }

            var rootKey = Registry.CurrentUser.OpenSubKey(root + "_Config");

            if (rootKey == null)
            {
                throw new NullReferenceException("Failed to open local registry root key.");
            }

            var packagesKey = rootKey.OpenSubKey("Packages");

            if (packagesKey == null)
            {
                throw new NullReferenceException("Failed to open packages key.");
            }

            foreach (var subKeyName in packagesKey.GetSubKeyNames())
            {
                var subKey = packagesKey.OpenSubKey(subKeyName);

                if (subKey == null)
                {
                    WriteVerbose(String.Format("Failed to open subkey [{0}].", subKey));
                    continue;
                }
                Guid id;
                if (!Guid.TryParse(subKeyName, out id))
                {
                    WriteVerbose(String.Format("Sub key [{0}] was not a valid Guid.", subKeyName));
                }

                Version v;
                Version.TryParse((string)subKey.GetValue("ProductVersion"), out v);

                var description = (string) subKey.GetValue("Description") ?? (string)subKey.GetValue("Default");

                var package = new VsPackage
                                  {
                                      Id = id,
                                      AssemblyName = (string) subKey.GetValue("Assembly"),
                                      Class = (string)subKey.GetValue("Class"),
                                      ProductName = (string)subKey.GetValue("ProductName"),
                                      CompanyName = (string)subKey.GetValue("CompanyName"),
                                      MinVersion = (string)subKey.GetValue("MinVersion"),
                                      ProductVersion = v,
                                      CodeBase = (string)subKey.GetValue("CodeBase"),
                                      Description = description
                                  };

                WriteObject(package);
            }
        }
    }
}
